﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<vector>
#include<array>
#include"Date.h"
using namespace std;

//顶层const与底层const
//int main()
//{
//	int i = 0;
//	int* const p1 = &i; // 顶层const
//	const int ci = 42; // 顶层const
//	const int* p2 = &ci; // 底层const
//	const int& r = ci; // 底层const
//	return 0;
//}


//constexpr 
//int size()
//{
//	int n = 10;
//	return n;
//}
//void test1()
//{
//	const int a = 1; // a是常量表达式
//	const int b = a + 1; // b是常量表达式
//	int c = 1; // c不是常量表达式
//	const int d = c; // d不是常量表达式
//	const int e = size(); // e不是常量表达式
//	// 常量表达式可以做数组⼤⼩，vs不⽀持变⻓数组，所以这⾥数组⼤⼩必须是编译时确认的
//	int arr[a];
//	constexpr int aa = 1;
//	constexpr int bb = aa + 1;
//	//constexpr int cc = c; // 报错
//	//constexpr int cc = size(); // 报错
//	//constexpr int* p1 = &d; //报错，权限放⼤了，constexpr修饰的是p1本⾝
//	const int* p2 = &d;
//	//constexpr const int* p3 = &d; //constexpr修饰的是p1本⾝，const修饰*p3
//}
//void test2()
//{
//	const int i = 1; // i是常量表达式
//	cout << i << endl;
//	//int* ptr = (int*)&i;
//	int* ptr = const_cast<int*>(&i); // 强制类型转换，将const int* 转换为 int*
//	*ptr += 1;
//	cout << i << endl;
//
//	int j = 1; // j是常量表达式
//	const int p = j; // p不是常量表达式
//	cout << p << endl;
//	ptr = const_cast<int*>(&p); // 强制类型转换，将const int* 转换为 int*
//	*ptr += 1;
//	cout << p << endl;
//}
//constexpr 函数
//constexpr int size()
//{
//	return 10;
//} 
//constexpr int func(int x)
//{
//	return 10 + x;
//} 
//constexpr int factorial(int n)
//{
//	return n <= 1 ? 1 : n * factorial(n - 1);
//} 
constexpr int fxx(int x)
{
	int i = x;
	i++;
	//cout << i << endl;
	return 10 + x;
}
//void test3()
//{
//	constexpr int x=size();
//	constexpr int y=func(1);
//	constexpr int z=factorial(5);
//	cout << x << endl;
//	cout << y << endl;
//	cout << z << endl;
//
//}
//void test4()
//{
//	// 编译时，N会被直接替换为10，constexpr函数默认就是inline
//	constexpr int N1 = size();
//	int arr1[N1];
//	// func传10时，func函数返回值是常量表达式，所以N2是常量表达式
//	constexpr int N2 = func(10);
//	int arr2[N2];
//	// func传10时，func函数返回值是常量表达式，所以N2是常量表达式
//	int i = 10;
//	constexpr int N3 = func(i); // 报错func返回的不是常量表达式
//	int N4 = func(i); // 不报错constexpr函数返回的不⼀是常量表达式
//	constexpr int fact5 = factorial(5); // 编译时计算
//	//constexpr修饰的函数可以有⼀些其他语句，但是这些语句运⾏时可以不执⾏任何操作就可以
//	// 如类型别名、空语句、using声明等
//	constexpr int N5 = fxx(10); // 报错
//
//}
template<typename T>
constexpr T Func(T t)
{
	return t;
}
void test5()
{
	int x = 2025;
	//constexpr Date d0(x, 9, 8); // 报错
	constexpr Date d1(2025, 9, 8);
	constexpr int y = d1.GetYear();
	Date d2(2025, 8, 11);
	int z = d2.GetYear();
	string ret1 = Func("111111"); // 普通函数
	constexpr int ret2 = Func(10);
}
// C++14允许的constexpr函数⽰例
constexpr int factorial(int n)
{
	int res = 1; // 允许局部变量
	for (int i = 2; i <= n; ++i) { // 允许循环
		res *= i;
	}
	return res; // 单⼀ return
}
constexpr size_t stringLength(const char* str) 
{
		size_t len = 0;
		while (str[len] != '\0')
			++len;
		return len;
}
void test6()
{
	constexpr size_t len = stringLength("Hello"); // 编译期计算：5
}
//支持更复杂的类型
struct Point {
	constexpr Point(double x, double y) : x(x), y(y) {}
	double x, y;
};
constexpr Point midpoint(Point a, Point b) {
	return Point((a.x + b.x) / 2, (a.y + b.y) / 2);
} 
constexpr std::array<int, 5> createArray() {
	std::array<int, 5> arr{};
	for (size_t i = 0; i < arr.size(); ++i) {
		arr[i] = i * i;
	} 
	return arr;
} 
constexpr int fibonacci(int n) {
	return (n <= 1) ? n : (fibonacci(n - 1) + fibonacci(n - 2));
}
void test7()
{
	Point p1 = midpoint({ 1.1,1.1 }, { 2.2,2.2 });
	constexpr Point p2 = midpoint({ 1.1,1.1 }, { 2.2,2.2 });
	constexpr std::array<int, 5> a1 = createArray();
	constexpr int fibArray[] = {
	fibonacci(0), fibonacci(1), fibonacci(2), fibonacci(3),
	fibonacci(4), fibonacci(5), fibonacci(6), fibonacci(7)
	};
}
//C++17允许的constexpr函数⽰例
template <typename T>
auto get_value(T t)
{
	//is_pointer_v 是 C++17 中引入的一个类型特性检查函数，
	// 用于在编译时检查一个类型是否为指针类型。
	//来源于<type_traits> 是C++标准库中非常重要的头文件，
	// 它提供了一系列编译时类型特性查询和转换的模板工具。

	if constexpr (std::is_pointer_v<T>)
	{
		return *t; // 仅当T为指针类型时实例化
	}
	else
	{
		return t; // ⾮指针类型时实例化
	}
}
void test8()
{
	// 使⽤⽰例
	int x = 42;
	auto v1 = get_value(x); // 返回x本⾝
	auto v2 = get_value(&x); // 解引⽤返回42
}
//lamabda表达式
//constexpr lambda⽰例
void test9()
{
	constexpr int n = 10;
	int y = 0;
	constexpr auto square = [n](int x) constexpr { return x * x * n; };
	constexpr int result = square(5); // 编译期计算：250
}
//C++20允许的constexpr函数⽰例
constexpr int dynamic_memory_example() {
	int* p = new int{ 42 }; // 编译期分配
	int value = *p;
	delete p; // 必须显式释放
	return value;
}
void test10()
{
	constexpr int v = dynamic_memory_example(); // 42
}

int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	//test6();
	return 0;
}